package controller

import (
	"fmt"
	"gitee.com/saxon134/go-utils/saData"
	"gitee.com/saxon134/go-utils/saData/saTime"
	"gitee.com/saxon134/workflow/api"
	"gitee.com/saxon134/workflow/db"
	"gitee.com/saxon134/workflow/db/project"
	"gitee.com/saxon134/workflow/db/user"
	"gitee.com/saxon134/workflow/enum"
	"gitee.com/saxon134/workflow/errs"
	"gitee.com/saxon134/workflow/interface/ioProject"
	"gitee.com/saxon134/workflow/interface/ioUser"
	"math/rand"
	"strings"
)

func ProjectList(c *api.Context) (resp *api.Response, err error) {
	in := new(ioProject.ListRequest)
	c.Bind(in)

	var userObj = new(user.TblUser)
	db.MySql.Where("id = ?", c.Account.Id).First(userObj)
	if userObj.Id <= 0 || userObj.Status != enum.Enable {
		return nil, errs.New(errs.ErrorUnauthorized)
	}

	var projAry = make([]*project.TblProject, 0, 10)

	//管理员
	if strings.Contains(userObj.Roles, saData.String(enum.Admin)) {
		if in.Status != 0 {
			db.MySql.Raw("select * from project where status = ? order by id desc", in.Status).Scan(&projAry)
		} else {
			db.MySql.Raw("select * from project order by id desc").Scan(&projAry)
		}
	} else
	//非管理员，只能拿到跟自己相关的项目
	{
		if in.Status != 0 {
			db.MySql.Raw(
				"select p.* from project p join project_rs rs on rs.project_id = p.id where rs.user_id = ? and rs.status = 1 and p.status in(1,2) order by p.id desc",
				userObj.Id,
			).Scan(&projAry)
		} else {
			db.MySql.Raw(
				"select p.* from project p join project_rs rs on rs.project_id = p.id where rs.user_id = ? and rs.status = 1 and p.status = ? order by p.id desc",
				userObj.Id, in.Status,
			).Scan(&projAry)
		}
	}

	var usrAry = make([]*user.TblUser, 0, 10)
	var rsAry = make([]*project.TblProjectRs, 0, len(projAry)*5)
	{
		var projIdAry = make([]int64, 0, len(projAry))
		for _, v := range projAry {
			projIdAry = append(projIdAry, v.Id)
		}

		db.MySql.Table(project.TBNProjectRs).
			Where("project_id in ? and status = 1", projIdAry).
			Select("user_id,project_id").Find(&rsAry)

		if len(rsAry) > 0 {
			var userIdAry = make([]int64, 0, len(rsAry))
			for _, rs := range rsAry {
				userIdAry = saData.AppendId(userIdAry, rs.UserId)
			}
			db.MySql.Table(user.TBNUser).Where("id in ?", userIdAry).Find(&usrAry)
		}
	}

	var resAry = make([]*ioProject.Item, 0, len(projAry))
	for _, v := range projAry {
		var item = &ioProject.Item{TblProject: v}

		for _, rs := range rsAry {
			if rs.ProjectId == v.Id {
				for _, u := range usrAry {
					if u.Id == rs.UserId {
						item.UserAry = append(item.UserAry, &ioUser.Basic{Name: u.Name, Id: u.Id})
						break
					}
				}
			}
		}

		resAry = append(resAry, item)
	}

	return &api.Response{Result: resAry}, nil
}

func ProjectSave(c *api.Context) (resp *api.Response, err error) {
	in := new(ioProject.SaveRequest)
	c.Bind(in)
	if in.Name == "" || in.Status == 0 {
		return nil, errs.New(errs.ErrorParams)
	}

	//默认当前用户
	if in.Leader <= 0 {
		in.TblProject.Leader = c.Account.Id
	}

	//不可重名
	var existId int64
	db.MySql.Raw("select id from project where name = ? and status in(1,2) limit 1", in.Name).Scan(existId)
	if existId > 0 {
		return nil, errs.New(errs.ErrorExisted)
	}

	//新建，随机设置背景色
	if in.Id <= 0 {
		var bgs = []string{"#50a45c", "#fa9653", "#d5f0da", "#f5eaf4", "#989082", "#d6c1f9", "#2d569b", "#fa696f", "#febace", "#c9fbcb"}
		in.Bg = bgs[rand.Intn(len(bgs))]
		in.CreateAt = saTime.Now()
	}

	//保存项目信息
	err = db.MySql.Save(in.TblProject).Error
	if err != nil {
		return nil, errs.New(err)
	}

	var userIdAry = make([]int64, 0, len(in.Users))
	userIdAry = append(userIdAry, in.Leader)
	for _, id := range in.Users {
		userIdAry = saData.AppendId(userIdAry, id)
	}

	//保存项目人员关系
	if in.TblProject.Id > 0 {
		err = db.MySql.Exec(
			"update project_rs set status = -1 where project_id = ? and user_id not in(?)",
			in.TblProject.Id, userIdAry,
		).Error
		if err != nil {
			return nil, errs.New(err)
		}
	}

	//已存在的关系
	var existAry = make([]int64, 0, 10)
	db.MySql.Raw("select user_id from project_rs where project_id = ? and status = 1", in.TblProject.Id).Scan(&existAry)

	//需要增加的关系
	var addAry = make([]int64, 0, len(userIdAry))
	for _, id := range userIdAry {
		if saData.InArray(id, existAry) == false {
			addAry = append(addAry, id)
		}
	}

	//新增关系
	if len(addAry) > 0 {
		var sql = ""
		for _, id := range addAry {
			sql += fmt.Sprintf("insert into project_rs (project_id,user_id,status)values(%d,%d,1);\n", in.TblProject.Id, id)
		}
		err = db.MySql.Exec(sql).Error
		if err != nil {
			return nil, errs.New(err)
		}
	}

	return &api.Response{Result: nil}, nil
}

func ProjectBrief(c *api.Context) (resp *api.Response, err error) {
	var in = new(ioProject.BriefRequest)
	c.Bind(in)
	if in.Id <= 0 {
		return nil, errs.New(errs.ErrorParams)
	}

	//当前用户身份
	var userObj = new(user.TblUser)
	db.MySql.Where("id = ?", c.Account.Id).First(userObj)
	if userObj.Id <= 0 || userObj.Status != enum.Enable {
		return nil, errs.New(errs.ErrorUnauthorized)
	}

	var resObj = new(ioProject.BriefResponse)

	//基础信息
	var proj = new(project.TblProject)
	db.MySql.Table(project.TBNProject).Where("id = ?", in.Id).First(proj)
	if proj.Id <= 0 {
		return nil, errs.New(errs.ErrorNotExisted)
	}
	resObj.TblProject = proj

	//成员
	var rsAry = make([]*project.TblProjectRs, 0, 10)
	db.MySql.Table(project.TBNProjectRs).Where("project_id = ? and status = 1", in.Id).Find(&rsAry)

	//非管理员，校验当前项目是否有权限
	if strings.Contains(userObj.Roles, saData.String(enum.Admin)) == false {
		var exist = false
		for _, v := range rsAry {
			if v.UserId == c.Account.Id {
				exist = true
				break
			}
		}
		if exist == false {
			return nil, errs.New(errs.ErrorUnauthorized)
		}
	}

	//成员基础信息
	var usrAry = make([]*user.TblUser, 0, 10)
	{
		if len(rsAry) > 0 {
			var userIdAry = make([]int64, 0, len(rsAry))
			for _, rs := range rsAry {
				userIdAry = saData.AppendId(userIdAry, rs.UserId)
			}
			db.MySql.Table(user.TBNUser).Where("id in ?", userIdAry).Find(&usrAry)

			var ary = make([]*ioUser.Basic, 0, len(usrAry))
			for _, v := range usrAry {
				ary = append(ary, &ioUser.Basic{Name: v.Name, Id: v.Id})
			}
			resObj.UserAry = ary
		}
	}

	//需求情况
	var group = make([]*ioProject.CntGroup, 0, 5)
	db.MySql.Raw("select count(*) cnt, status from demand where project_id = ? group by status", in.Id).Scan(&group)
	//-1-废弃 1-待确认 2-开发中 3-测试中 4-已完成 5-已上线
	for _, v := range group {
		resObj.Demand.Total += v.Cnt
		if v.Status == 4 || v.Status == 5 {
			resObj.Demand.Done += v.Cnt
		} else if v.Status == 1 || v.Status == 2 || v.Status == 3 {
			resObj.Demand.Todo += v.Cnt
		} else {
			resObj.Demand.Discard += v.Cnt
		}
	}

	//任务情况
	group = make([]*ioProject.CntGroup, 0, 5)
	db.MySql.Raw("select count(*) cnt, status from job where project_id = ? group by status", in.Id).Scan(&group)
	//0-待处理 1-已完成 -1-已废弃
	for _, v := range group {
		resObj.Job.Total += v.Cnt
		if v.Status == 0 {
			resObj.Job.Todo += v.Cnt
		} else if v.Status == 1 {
			resObj.Job.Done += v.Cnt
		} else {
			resObj.Job.Discard += v.Cnt
		}
	}

	//测试case情况

	//bug情况

	return &api.Response{Result: resObj}, nil
}
